/**
 @file sys_usw_lb_hash.h

 @date 2009-10-21

 @version v2.0

*/

#ifndef _SYS_USW_HASH_H
#define _SYS_USW_HASH_H
#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_debug.h"
#include "sys_usw_register.h"

/****************************************************************
*
* Defines and Macros
*
****************************************************************/

extern sys_register_master_t *p_usw_register_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

#define SYS_LB_HASH_INIT_CHECK() \
		do { \
			LCHIP_CHECK(lchip);\
			if (NULL == p_usw_register_master[lchip]){ \
				return CTC_E_NOT_INIT; } \
		} while (0)

#define SYS_LB_HASH_DBG_OUT(level, FMT, ...)\
    do\
    {\
        CTC_DEBUG_OUT(linkagg, linkagg, LINKAGG_SYS, level, FMT, ##__VA_ARGS__);\
    } while (0)

#define SYS_LB_HASH_IS_COMPATIBLE_MODE \
    (DRV_FROM_TMM(lchip) && MCHIP_CAP(SYS_CAP_LB_HASH_SELECT_NUM) == SYS_USW_LB_HASH_CTL_NUM)

#define SYS_LB_HASH_IS_ONLY_L2_FIELD(flag) \
    ((((flag) & (CTC_LB_HASH_FIELD_MACSA_LO | CTC_LB_HASH_FIELD_MACSA_MI | CTC_LB_HASH_FIELD_MACSA_HI \
                | CTC_LB_HASH_FIELD_MACDA_LO | CTC_LB_HASH_FIELD_MACDA_MI | CTC_LB_HASH_FIELD_MACDA_HI \
                | CTC_LB_HASH_FIELD_ETHER_TYPE | CTC_LB_HASH_FIELD_SVLAN | CTC_LB_HASH_FIELD_CVLAN)) != 0) \
    && (((flag) & ~(CTC_LB_HASH_FIELD_SRC_CHIP_ID | CTC_LB_HASH_FIELD_DST_CHIP_ID | CTC_LB_HASH_FIELD_SRC_PORT | CTC_LB_HASH_FIELD_DST_PORT \
                | CTC_LB_HASH_FIELD_MACSA_LO | CTC_LB_HASH_FIELD_MACSA_MI | CTC_LB_HASH_FIELD_MACSA_HI \
                | CTC_LB_HASH_FIELD_MACDA_LO | CTC_LB_HASH_FIELD_MACDA_MI | CTC_LB_HASH_FIELD_MACDA_HI \
                | CTC_LB_HASH_FIELD_ETHER_TYPE | CTC_LB_HASH_FIELD_SVLAN | CTC_LB_HASH_FIELD_CVLAN \
                | CTC_LB_HASH_FIELD_VNI_LO | CTC_LB_HASH_FIELD_VNI_HI | CTC_LB_HASH_FIELD_INNER)) == 0))

enum sys_hash_poly_e
{
    SYS_LB_HASHPOLY_CRC8_POLY1,
    SYS_LB_HASHPOLY_CRC8_POLY2,
    SYS_LB_HASHPOLY_XOR8,
    SYS_LB_HASHPOLY_CRC10_POLY1,
    SYS_LB_HASHPOLY_CRC10_POLY2,
    SYS_LB_HASHPOLY_XOR16,
    SYS_LB_HASHPOLY_CRC16_POLY1,
    SYS_LB_HASHPOLY_CRC16_POLY2,
    SYS_LB_HASHPOLY_CRC16_POLY3,
    SYS_LB_HASHPOLY_CRC16_POLY4,
    SYS_LB_HASHPOLY_CRC16_POLY5,
    SYS_LB_HASHPOLY_CRC16_POLY6,
    SYS_LB_HASHPOLY_CRC32_POLY1,
    SYS_LB_HASHPOLY_CRC32_POLY2,
    SYS_LB_HASHPOLY_NO_CALC,
    SYS_LB_HASHPOLY_POLY_MAX
};
typedef enum sys_hash_poly_e sys_hash_poly_t;

enum sys_hash_control_e
{
    SYS_LB_HASH_CONTROL_L2VPN_USE_OUTER_L3 = CTC_LB_HASH_CONTROL_MAX + 1,         /* enable l2vpn use outer l3 fields. */
    SYS_LB_HASH_CONTROL_L3VPN_USE_OUTER_L3,         /* enable l3vpn use outer l3 fields. */
    SYS_LB_HASH_CONTROL_MPLS_TRANSMIT_MODE,         /* mpls transmit key select mode,
                                                       mode 0: use MacSa and MacDa to hash key
                                                       mode 1: use mpls label2 to hash key
                                                       mode 2: use l4 sourc port and l4 dest port to hash key*/
    SYS_LB_HASH_CONTROL_GRE_INNER_L2_USE_VSID,  /* enable gre use inner l2 vsid field. */
    SYS_LB_HASH_CONTROL_VXLAN_INNER_L2_USE_VNI,  /* enable vxlan use inner l2 vni field. */
    SYS_LB_HASH_CONTROL_UDF_BULK_EN              /* enable 32bit udf */
};
typedef enum sys_hash_control_e sys_hash_control_t;

#define HASH_KEY_TEMPLATE0(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
    {\
        CTC_BIT_SET(flag, 0);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 1);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
    {\
        CTC_BIT_SET(flag, 2);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 3);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_LO))\
    {\
        CTC_BIT_SET(flag, 4);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_MI))\
    {\
        CTC_BIT_SET(flag, 5);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_HI))\
    {\
        CTC_BIT_SET(flag, 6);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_LO))\
    {\
        CTC_BIT_SET(flag, 7);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_MI))\
    {\
        CTC_BIT_SET(flag, 8);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_HI))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_ETHER_TYPE))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_LO) && 1 == mode)\
    {\
        CTC_BIT_SET(flag, 11);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SVLAN) && 0 == mode)\
    {\
        CTC_BIT_SET(flag, 11);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_HI)&& 1 == mode)\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_CVLAN)&& 0 == mode)\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
}while(0);\

#define GET_HASH_KEY_TEMPLATE0(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_ETHER_TYPE);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SVLAN);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_CVLAN);\
    }\
}while(0);\

#define HASH_KEY_TEMPLATE1(flag, value)\
do{\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
    {\
        CTC_BIT_SET(flag, 0);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 1);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
    {\
        CTC_BIT_SET(flag, 2);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 3);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_LO))\
    {\
        CTC_BIT_SET(flag, 4);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_MI))\
    {\
        CTC_BIT_SET(flag, 5);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_HI))\
    {\
        CTC_BIT_SET(flag, 6);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_LO))\
    {\
        CTC_BIT_SET(flag, 7);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_MI))\
    {\
        CTC_BIT_SET(flag, 8);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_HI))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_ETHER_TYPE))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SVLAN))\
    {\
        CTC_BIT_SET(flag, 11);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_INGRESS_NICKNAME))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_EGRESS_NICKNAME))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
}while(0);\

#define GET_HASH_KEY_TEMPLATE1(flag, value)\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_ETHER_TYPE);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SVLAN);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_INGRESS_NICKNAME);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_EGRESS_NICKNAME);\
    }\
}while(0);\



#define HASH_KEY_TEMPLATE2(flag, value)\
do{\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
    {\
        CTC_BIT_SET(flag, 0);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 1);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
    {\
        CTC_BIT_SET(flag, 2);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 3);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FCOE_SID_LO))\
    {\
        CTC_BIT_SET(flag, 4);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FCOE_SID_HI))\
    {\
        CTC_BIT_SET(flag, 5);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FCOE_DID_LO))\
    {\
        CTC_BIT_SET(flag, 6);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FCOE_DID_HI))\
    {\
        CTC_BIT_SET(flag, 7);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_LO))\
    {\
        CTC_BIT_SET(flag, 8);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_HI))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
}while (0);\

#define GET_HASH_KEY_TEMPLATE2(flag,value )\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FCOE_SID_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FCOE_SID_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FCOE_DID_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FCOE_DID_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_HI);\
    }\
}while(0);\

#define HASH_KEY_TEMPLATE3(flag, value, mode) \
    do {\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
        {\
            CTC_BIT_SET(flag, 0);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
        {\
            CTC_BIT_SET(flag, 1);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
        {\
            CTC_BIT_SET(flag, 2);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
        {\
            CTC_BIT_SET(flag, 3);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL0_LO) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 4);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_LO) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 4);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_L4_SRCPORT) && 2 == mode)\
        {\
            CTC_BIT_SET(flag, 4);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL1_LO) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 5);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_MI) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 5);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_L4_DSTPORT) && 2 == mode)\
        {\
            CTC_BIT_SET(flag, 5);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL2_LO) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 6);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_HI) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 6);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_PROTOCOL) && 2 == mode)\
        {\
            CTC_BIT_SET(flag, 6);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL0_HI) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 7);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_LO) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 7);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_LO))\
        {\
            CTC_BIT_SET(flag, 8);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_HI))\
        {\
            CTC_BIT_SET(flag, 9);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_LO))\
        {\
            CTC_BIT_SET(flag, 10);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_HI))\
        {\
            CTC_BIT_SET(flag, 11);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL1_HI) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 12);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_MI) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 12);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_LABEL2_HI) && 0 == mode)\
        {\
            CTC_BIT_SET(flag, 13);\
        }\
        if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_HI) && 1 == mode)\
        {\
            CTC_BIT_SET(flag, 13);\
        }\
        if (!DRV_FROM_TMM(lchip)) \
        { \
            if ((CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_LO) && CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_MI) && CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACDA_HI))\
                || (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_LO) && CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_MI) && CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_MACSA_HI)))\
            {\
                CTC_BIT_SET(flag, 13);\
            }\
        } \
    }while (0);\

#define GET_HASH_KEY_TEMPLATE3(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL0_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10) && 2 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_L4_SRCPORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL1_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20) && 2 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_L4_DSTPORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL2_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACSA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40) && 2 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_PROTOCOL);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL0_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL1_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_MI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 0 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_LABEL2_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 1 == mode)\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_MACDA_HI);\
    }\
}while(0);\

#define HASH_KEY_TEMPLATE4(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
    {\
        CTC_BIT_SET(flag, 0);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 1);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
    {\
        CTC_BIT_SET(flag, 2);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 3);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_LO))\
    {\
        CTC_BIT_SET(flag, 4);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_HI))\
    {\
        CTC_BIT_SET(flag, 5);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_LO))\
    {\
        CTC_BIT_SET(flag, 6);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_HI))\
    {\
        CTC_BIT_SET(flag, 7);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_PROTOCOL))\
    {\
        CTC_BIT_SET(flag, 8);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_L4_SRCPORT) && !CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_LO) && CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_L4_DSTPORT)&& !CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_HI) &&  CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SVLAN))\
    {\
        CTC_BIT_SET(flag, 11);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_LO) && 1 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_LO) && 0 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FLOWLABEL_LO) && 2 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_HI) && 1 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_HI) && 0 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FLOWLABEL_HI) && 2 == (mode&0x3))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
}\
while(0);

#define GET_HASH_KEY_TEMPLATE4(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_PROTOCOL);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200)&& !CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_L4_SRCPORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200)&& CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400)&& !CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_L4_DSTPORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400) && CTC_IS_BIT_SET(mode, 3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SVLAN);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 1 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 0 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 2 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FLOWLABEL_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 1 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 0 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 2 == (mode&0x3))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FLOWLABEL_HI);\
    }\
}while(0);\

#define HASH_KEY_TEMPLATE5(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_PORT))\
    {\
        CTC_BIT_SET(flag, 0);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 1);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_PORT))\
    {\
        CTC_BIT_SET(flag, 2);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_DST_CHIP_ID))\
    {\
        CTC_BIT_SET(flag, 3);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_LO))\
    {\
        CTC_BIT_SET(flag, 4);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_SA_HI))\
    {\
        CTC_BIT_SET(flag, 5);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_LO))\
    {\
        CTC_BIT_SET(flag, 6);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_IP_DA_HI))\
    {\
        CTC_BIT_SET(flag, 7);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_GRE_PROTOCOL))\
    {\
        CTC_BIT_SET(flag, 8);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_LO) && 1 == (mode&0x1))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_GRE_KEY_LO) && 0 == (mode&0x1))\
    {\
        CTC_BIT_SET(flag, 9);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_VNI_HI) && 1 == (mode&0x1))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_GRE_KEY_HI) && 0 == (mode&0x1))\
    {\
        CTC_BIT_SET(flag, 10);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_SVLAN))\
    {\
        CTC_BIT_SET(flag, 11);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_LO)&& 0 == (mode&0x2))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FLOWLABEL_LO)&& 0x2 == (mode&0x2))\
    {\
        CTC_BIT_SET(flag, 12);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_UDF_HI)&& 0 == (mode&0x2))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
    if (CTC_FLAG_ISSET(value, CTC_LB_HASH_FIELD_FLOWLABEL_HI)&& 0x2 == (mode&0x2))\
    {\
        CTC_BIT_SET(flag, 13);\
    }\
}while (0);\

#define GET_HASH_KEY_TEMPLATE5(flag, value, mode)\
do{\
    if (CTC_FLAG_ISSET(flag, 0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SRC_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x4))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_PORT);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x8))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_DST_CHIP_ID);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x10))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x20))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_SA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x40))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x80))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_IP_DA_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x100))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_GRE_PROTOCOL);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200) && 1 == (mode&0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x200) && 0 == (mode&0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_GRE_KEY_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400) && 1 == (mode&0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_VNI_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x400) && 0 == (mode&0x1))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_GRE_KEY_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x800))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_SVLAN);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 0 == (mode&0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x1000) && 0x2 == (mode&0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FLOWLABEL_LO);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 0 == (mode&0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_UDF_HI);\
    }\
    if (CTC_FLAG_ISSET(flag, 0x2000) && 0x2 == (mode&0x2))\
    {\
        CTC_SET_FLAG(value, CTC_LB_HASH_FIELD_FLOWLABEL_HI);\
    }\
}while(0);\

#define SYS_LB_HASH_SEL_STR \
"l2",\
"ipv4",\
"ipv4-tcp-udp",\
"ipv4-tcp-udp-ports-equal",\
"ipv4-vxlan",\
"ipv4-gre",\
"ipv4-nvgre",\
"ipv6",\
"ipv6-tcp-udp",\
"ipv6-tcp-udp-ports-equal",\
"ipv6-vxlan",\
"ipv6-gre",\
"ipv6-nvgre",\
"nvgre-inner-l2",\
"nvgre-inner-ipv4",\
"nvgre-inner-ipv6",\
"vxlan-inner-l2",\
"vxlan-inner-ipv4",\
"vxlan-inner-ipv6",\
"mpls",\
"mpls-inner-ipv4",\
"mpls-inner-ipv6",\
"mpls-vpws-raw",\
"mpls-l2vpn-inner-l2",\
"mpls-l2vpn-inner-ipv4",\
"mpls-l2vpn-inner-ipv6",\
"mpls-l3vpn-inner-ipv4",\
"mpls-l3vpn-inner-ipv6",\
"trill-outer-l2-only",\
"trill",\
"trill-inner-l2",\
"trill-inner-ipv4",\
"trill-inner-ipv6",\
"trill-decap-inner-l2",\
"trill-decap-inner-ipv4",\
"trill-decap-inner-ipv6",\
"fcoe",\
"flex-tnl-inner-l2",\
"flex-tnl-inner-ipv4",\
"flex-tnl-inner-ipv6",\
"udf",\
"max"

#define SYS_LB_HASH_CTL_STR \
"l2-only",\
"disable-ipv4",\
"disable-ipv6",\
"disable-mpls",\
"disable-fcoe",\
"disable-trill",\
"disable-tunnel-ipv4-in4",\
"disable-tunnel-ipv6-in4",\
"disable-tunnel-gre-in4",\
"disable-tunnel-nvgre-in4",\
"disable-tunnel-vxlan-in4",\
"disable-tunnel-ipv4-in6",\
"disable-tunnel-ipv6-in6",\
"disable-tunnel-gre-in6",\
"disable-tunnel-nvgre-in6",\
"disable-tunnel-vxlan-in6",\
"mpls-exclude-rsv",\
"ipv6-addr-collapse",\
"ipv6-use-flow-label",\
"nvgre-aware",\
"fcoe-symmetric-en",\
"udf-select-mode",\
"udf-data-byte-mask",\
"use-mapped-vlan",\
"ipv4-symmetric-en",\
"ipv6-symmetric-en",\
"l2vpn-use-inner-l2",\
"vpws-use-inner",\
"trill-decap-use-inner-l2",\
"trill-transmit-mode",\
"mpls-entropy-en",\
"mpls-label2-en",\
"vxlan-use-inner-l2",\
"nvgre-use-inner-l2",\
"flex-tnl-use-inner-l2",\
"hash-seed",\
"hash-type-a",\
"hash-type-b",\
"hash-seed-use-udf",\
"udf-data-bit-mask",\
"max"

#endif

